/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */

package MinaClient;

import java.net.InetSocketAddress;
import java.nio.charset.Charset;
import org.apache.log4j.Logger;
import org.apache.mina.core.future.ConnectFuture;
import org.apache.mina.core.service.IoConnector;
import org.apache.mina.core.service.IoHandler;
import org.apache.mina.core.service.IoHandlerAdapter;
import org.apache.mina.core.session.IoSession;
import org.apache.mina.filter.codec.ProtocolCodecFilter;
import org.apache.mina.filter.codec.textline.LineDelimiter;
import org.apache.mina.filter.codec.textline.TextLineCodecFactory;
import org.apache.mina.transport.socket.nio.NioSocketConnector;

/**
 *
 * @author Chen Cheng
 */
public class MinaClient implements MinaClientInterface{
    private String HOSTNAME;
    private int PORT;
    private final IoHandler handler; // Client handler
    private IoSession session;
    MinaClientMessage rmsg;
    
    private static Logger logger = Logger.getLogger(MinaClient.class);
    
    IoConnector connector;
    
    public MinaClient() {       
        rmsg = new MinaClientMessage();
        this.handler = new ClientHandler(rmsg);
    }
    
    public MinaClient(String HOSTNAME,int PORT,MinaClientMessage rmsg) {
        this.HOSTNAME = HOSTNAME;
        this.PORT = PORT;
        
        this.handler = new ClientHandler(rmsg);
        
        // Create a NIO client program
        connector = new NioSocketConnector();
        
        // Set overtime
        connector.setConnectTimeoutMillis(20);
        
        // add Filter
        connector.getFilterChain().addLast("codec", new ProtocolCodecFilter(
                new TextLineCodecFactory(Charset.forName("UTF-8"),
                LineDelimiter.WINDOWS.getValue(),
                LineDelimiter.WINDOWS.getValue())));
        
        //ClientHandler ch = new ClientHandler();
        connector.setHandler(handler);
        session = null;
    }
    
    public void createConnect(String HOSTNAME,int PORT){       
        this.HOSTNAME = HOSTNAME;
        this.PORT = PORT;
        
       // handler = new ClientHandler(rmsg);
        
        // Create a NIO client program
        connector = new NioSocketConnector();
        
        // Set overtime
        connector.setConnectTimeoutMillis(20);
        
        // add Filter
        connector.getFilterChain().addLast("codec", new ProtocolCodecFilter(
                new TextLineCodecFactory(Charset.forName("UTF-8"),
                LineDelimiter.WINDOWS.getValue(),
                LineDelimiter.WINDOWS.getValue())));
        
        //ClientHandler ch = new ClientHandler();
        connector.setHandler(handler);
        session = null;
    }
    
    @Override
    public void sendMessage (String msg) {
        try {
            ConnectFuture future = connector.connect(new InetSocketAddress(HOSTNAME,PORT));
            future.awaitUninterruptibly();
            session = future.getSession();   
            session.write(msg);          
        } catch (Exception e) {
            logger.error("Client connect exception..", e);
        }
        
//        try {  
//            Thread.sleep(500);  
//        } catch (InterruptedException e) {  
//            e.printStackTrace();  
//        }
        //System.out.println(handler.getRMessage()); 
        session.getCloseFuture().awaitUninterruptibly(100);
        connector.dispose();
    }
    
    @Override
    public String receiveMessage() {
//        while (!rmsg.getSatues()) {
//            System.out.println("Waiting Server received!");
//        }
        return rmsg.receiveMessage();
    }
}

class ClientHandler extends IoHandlerAdapter { 
    CallbackMsg callback;
   
    public ClientHandler(CallbackMsg callback) {
        this.callback = callback;
    }
    
    @Override
    public void messageReceived(IoSession arg0, Object message) throws Exception { 
        callback.setMessage(message.toString());
        callback.setSatues(true);
    }
    
    @Override
    public void exceptionCaught(IoSession arg0, Throwable arg1) throws Exception { 
        
    }       
} 


